package vn.edu.saigontech.ncms.web.offering;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.hssf.util.HSSFColor;

import vn.edu.saigontech.ncms.model.bookstore.ItemTitle;
import vn.edu.saigontech.ncms.model.info.NextOffering;
import vn.edu.saigontech.ncms.model.info.Offering;
import vn.edu.saigontech.ncms.model.program.Level;
import vn.edu.saigontech.ncms.model.system.Shift;
import vn.edu.saigontech.ncms.service.ItemTitleService;
import vn.edu.saigontech.ncms.service.LevelService;
import vn.edu.saigontech.ncms.service.NextOfferingService;
import vn.edu.saigontech.ncms.service.OfferingService;
import vn.edu.saigontech.ncms.service.ProgramService;
import vn.edu.saigontech.ncms.service.ShiftService;
import vn.edu.saigontech.ncms.util.DateUtil;
import vn.edu.saigontech.ncms.util.ExcelUtil;
import vn.edu.saigontech.ncms.util.I18n;
import vn.edu.saigontech.ncms.web.BaseAction;

@SuppressWarnings("serial")
public class NextOfferingAction extends BaseAction {
	
	private Long offeringId;
	
	private Long id;
	private String name;
	private Long programId;
	private Long levelId;
	private Long shiftId;
	private String startDate;
	private String endDate;
	
	private int month;
	private int year;
	
	public String showAdd() {
		Offering offering = OfferingService.INSTANCE.findById(this.offeringId);
		Date startDate = DateUtil.addDay(offering.getEndDate(), 10);
		int acc = offering.getLevel().getWeeks() * 7 - 3;
		Date endDate = DateUtil.addDay(startDate, acc);
		Level nextLevel = LevelService.INSTANCE.findNextLevel(offering.getLevel());
		REQUEST().setAttribute("offering", offering);
		REQUEST().setAttribute("nextLevel", nextLevel);
		REQUEST().setAttribute("startDate", startDate);
		REQUEST().setAttribute("endDate", endDate);
		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAll());
		REQUEST().setAttribute("shifts", ShiftService.INSTANCE.findAll());
		return SUCCESS;
	}
	
	public String add() {
		NextOffering nextOffering = new NextOffering();
		Offering offering  = OfferingService.INSTANCE.findById(this.offeringId);
		
		nextOffering.setName(this.name);
		Level level = LevelService.INSTANCE.findById(levelId);
		nextOffering.setLevel(level);
		nextOffering.setShift(ShiftService.INSTANCE.findById(shiftId));
		nextOffering.setStartDate(DateUtil.fromString(this.startDate, this.i18n("format.date")));
		nextOffering.setEndDate(DateUtil.fromString(this.endDate, this.i18n("format.date")));
		
		nextOffering = NextOfferingService.INSTANCE.persist(nextOffering);
		offering.setNextOffering(nextOffering);
		this.id = nextOffering.getId();
		return SUCCESS;
	}
	
	public String showEdit() {
		Offering offering = OfferingService.INSTANCE.findById(this.offeringId);
		REQUEST().setAttribute("offering", offering);
		REQUEST().setAttribute("nextOffering", offering.getNextOffering());
		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAll());
		REQUEST().setAttribute("shifts", ShiftService.INSTANCE.findAll());
		return SUCCESS;
	}
	
	public String edit() {
		NextOffering nextOffering = NextOfferingService.INSTANCE.findById(this.id);
		
		nextOffering.setName(this.name);
		Level level = LevelService.INSTANCE.findById(levelId);
		nextOffering.setLevel(level);
		nextOffering.setShift(ShiftService.INSTANCE.findById(shiftId));
		nextOffering.setStartDate(DateUtil.fromString(this.startDate, this.i18n("format.date")));
		nextOffering.setEndDate(DateUtil.fromString(this.endDate, this.i18n("format.date")));
		
		NextOfferingService.INSTANCE.persist(nextOffering);
		
		return SUCCESS;
	}
	
	public String report() {
		Date fromDate = DateUtil.getStartDateOfMonth(month, year);
		Date toDate = DateUtil.getEndDateOfMonth(month, year);
		
		RESPONSE().setContentType("application/vnd.ms-excel");
		RESPONSE().setHeader("Content-disposition","attachment; filename=\""+ "New Timetable - " + (month + 1) + ".xls\"");
		
		try {
			HSSFWorkbook workbook = new HSSFWorkbook();
			HSSFSheet sheet = workbook.createSheet("Report");
			
			HSSFFont fontBold18 = ExcelUtil.makeFont(workbook, "Times New Roman", 18, true);
			HSSFFont fontBold11 = ExcelUtil.makeFont(workbook, "Times New Roman", 11, true);
			HSSFFont fontNormal11 = ExcelUtil.makeFont(workbook, "Times New Roman", 11, false);
			HSSFFont fontPurpleNormal11 = ExcelUtil.makeFont(workbook, "Times New Roman", 11, false);
			fontPurpleNormal11.setColor(HSSFColor.VIOLET.index);
			
			HSSFCellStyle styleCenter_B18 = ExcelUtil.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, fontBold18);
			HSSFCellStyle styleCenter_B11 = ExcelUtil.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, fontBold11);
			HSSFCellStyle styleCenter_N11 = ExcelUtil.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, fontNormal11);
			HSSFCellStyle stylePurpleCenter_N11 = ExcelUtil.makeCellStyle(workbook, HSSFCellStyle.ALIGN_CENTER, HSSFCellStyle.VERTICAL_CENTER, fontPurpleNormal11);

			int r = 0;
			HSSFRow row = sheet.createRow(r);
			
			HSSFCell cell = row.createCell(0, HSSFCell.CELL_TYPE_STRING);
			cell.setCellStyle(styleCenter_B18);
			row.setHeightInPoints(31);
			String month = DateUtil.getMonthAsFullString(fromDate);
			cell.setCellValue(new HSSFRichTextString("TIMETABLE FOR NEW CLASSES IN " + month.toUpperCase() + " " + year));
			sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 8));
			
			r = r + 1;
			row = sheet.createRow(r);
			row.setHeightInPoints(31);
			
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 0, "No.", 256*5, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 1, "Old Class", 256*11, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 2, "Old Sts.", 256*10, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 3, "End Date", 256*12, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 4, "New Class", 256*12, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 5, "Book & CD", 256*37, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 6, "Day / Time", 256*23, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 7, "Start Date", 256*12, styleCenter_B11);
			ExcelUtil.makeColumnLabel(workbook, sheet, row, 8, "End Date", 256*12, styleCenter_B11);
			
			int index = 1;
			List<NextOffering> offerings = NextOfferingService.INSTANCE.findOrderByDate(fromDate, toDate);
			for(NextOffering nextOffering : offerings) {
				Offering offering = OfferingService.INSTANCE.findByNextOffering(nextOffering.getId());
				if (offering == null) {
					continue;
				}
				
				r = r + 1;
				row = sheet.createRow(r);
				row.setHeightInPoints(32);
				
				cell = row.createCell(0, HSSFCell.CELL_TYPE_NUMERIC);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(index++);
				
				cell = row.createCell(1, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(offering.getName()));
				
				cell = row.createCell(2, HSSFCell.CELL_TYPE_NUMERIC);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(offering.getNumberOfActiveStudents());
				
				String oldEndDate = DateUtil.toString(offering.getEndDate(), new I18n().getMessage("format.vndate"));
				cell = row.createCell(3, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(oldEndDate));
				
				cell = row.createCell(4, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(nextOffering.getName()));
				
				List<ItemTitle> titles = ItemTitleService.INSTANCE.findByLevel(nextOffering.getLevel());
				StringBuffer buffer = new StringBuffer();
				for(int i = 0; i < titles.size(); i++) {
					if(i == (titles.size() - 1)) {
						buffer.append(titles.get(i).getTitle());
					} else
						buffer.append(titles.get(i).getTitle() + ", ");
				}
				cell = row.createCell(5, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(stylePurpleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(buffer.toString()));
				
				Shift shift = nextOffering.getShift();
				
				Set<Integer> days = offering.getDays();
				Iterator<Integer> iterator = days.iterator();
				StringBuffer daysBuffer = new StringBuffer();
				int tmp = 0;
				while(iterator.hasNext()) {
					if(tmp != days.size() - 1) {
						daysBuffer.append(DateUtil.getDateOfWeekAsChar(iterator.next()) + ".");
					} else {
						daysBuffer.append(DateUtil.getDateOfWeekAsChar(iterator.next()));
					}
					tmp++;
				}
				cell = row.createCell(6, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(shift + " " + daysBuffer.toString()));
				
				String startDate = DateUtil.toString(nextOffering.getStartDate(), new I18n().getMessage("format.vndate"));
				cell = row.createCell(7, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(startDate));
				
				String endate = DateUtil.toString(nextOffering.getEndDate(), new I18n().getMessage("format.vndate"));
				cell = row.createCell(8, HSSFCell.CELL_TYPE_STRING);
				cell.setCellStyle(styleCenter_N11);
				cell.setCellValue(new HSSFRichTextString(endate));
			}
			workbook.write(RESPONSE().getOutputStream());
		} catch(Exception ex) {
			ex.printStackTrace();
		}
		return NONE;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Long getProgramId() {
		return programId;
	}

	public void setProgramId(Long programId) {
		this.programId = programId;
	}

	public Long getLevelId() {
		return levelId;
	}

	public void setLevelId(Long levelId) {
		this.levelId = levelId;
	}

	public Long getShiftId() {
		return shiftId;
	}

	public void setShiftId(Long shiftId) {
		this.shiftId = shiftId;
	}

	public String getStartDate() {
		return startDate;
	}

	public void setStartDate(String startDate) {
		this.startDate = startDate;
	}

	public String getEndDate() {
		return endDate;
	}

	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

	public Long getOfferingId() {
		return offeringId;
	}

	public void setOfferingId(Long offeringId) {
		this.offeringId = offeringId;
	}

	public int getMonth() {
		return month;
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}
}
